package com.hnzq.cloud.freshorderassembly.controller;


import com.fasterxml.jackson.core.JsonProcessingException;
import com.hnzq.cloud.OrderAPI;
import com.hnzq.cloud.dto.AddOrderDto;
import com.hnzq.cloud.dto.OrderDto;
import com.hnzq.cloud.dto.PageOrdersDto;
import com.hnzq.cloud.dto.UpdateOrderStatusDto;
import com.hnzq.cloud.freshorderassembly.domain.FreOrder;
import com.hnzq.cloud.freshorderassembly.exception.FreshException;
import com.hnzq.cloud.freshorderassembly.exception.OrderException;
import com.hnzq.cloud.freshorderassembly.service.IFreOrderService;
import com.hnzq.cloud.freshorderassembly.util.WoniuBeanUtils;
import com.hnzq.cloud.model.Result;
import com.hnzq.cloud.param.*;
import io.seata.spring.annotation.GlobalTransactional;
import org.redisson.api.RBucket;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author 周皓月
 * @since 2022-02-06
 */
@RestController
@RequestMapping("/freOrder")
public class FreOrderController implements OrderAPI {

    @Autowired
    private IFreOrderService fos;


    @Resource
    private RedissonClient redisson;


    /**
     * 新增订单
     * @param addOrderParam
     * @return
     */
    @Override
    @GlobalTransactional
    public Result<AddOrderDto> addOrder(AddOrderParam addOrderParam) {
        AddOrderDto addOrderDto = fos.addOrder(addOrderParam);
        System.out.println(addOrderDto);
        return Result.newInstance().setMessage("新增成功").setData(addOrderDto);
    }

    /**
     * 分页条件查询订单（用户订单展示）
     * @param findOrderParam
     * @return
     */
    @Override
    public Result<PageOrdersDto> findOrderByCondition(FindOrderParam findOrderParam) {
        return Result.newInstance().setMessage("查询成功").setData(fos.findOrderByCondition(findOrderParam));
    }

    /**
     * 根据单个订单id查询订单
     * @param orderId
     * @return
     */
    @Override
    public Result<OrderDto> findOrderByOrderId(Integer orderId) {
        FreOrder orderByOrderId = fos.findOrderByOrderId(orderId);
        OrderDto orderDto = WoniuBeanUtils.copyObject(orderByOrderId, OrderDto.class);
        return Result.newInstance().setMessage("查询成功").setData(orderDto);
    }


    /**
     * 修改订单状态
     * @param updateOrderStatusParam
     * @return
     */
    @Override
    @GlobalTransactional
    public Result<UpdateOrderStatusDto> updateOrderStatus(UpdateOrderStatusParam updateOrderStatusParam) throws JsonProcessingException {
        return Result.newInstance().setMessage("修改成功").setData(fos.updateOrderStatus(updateOrderStatusParam));
    }

    /**
     * 删除订单
     * @param removeOrderParam
     * @return
     */
    @Override
    @GlobalTransactional
    public Result<Boolean> removeOrder(RemoveOrderParam removeOrderParam) throws JsonProcessingException {
        if (fos.removeOrder(removeOrderParam)){
            return Result.newInstance().setMessage("删除成功");
        }
        return Result.newInstance().setCode(500).setMessage("删除失败");
    }

    /**
     * 根据单个站点id查询所有订单
     * @param findOrderBySiteIdParam
     * @return
     */
    @Override
    public Result<PageOrdersDto> findOrderBySiteId(FindOrderBySiteIdParam findOrderBySiteIdParam) {
        return Result.newInstance().setMessage("查询成功").setData(fos.findOrderBySiteId(findOrderBySiteIdParam));
    }

    /**
     * 根据多个站点id查询所有订单
     * @param findOrderBySiteIdListParam
     * @return
     */
    @Override
    public Result<PageOrdersDto> findOrderBySiteIdList(FindOrderBySiteIdListParam findOrderBySiteIdListParam) {
        return Result.newInstance().setMessage("查询成功").setData(fos.findOrderBySiteIdList(findOrderBySiteIdListParam));
    }

    /**
     * 模拟支付宝支付
     * @return
     */
    @Override
    @GlobalTransactional
    public Result<String> payForZFB(Integer orderId) throws JsonProcessingException {

//        //获取锁对象
//        RLock lock = redisson.getLock("payForZFB");
//
//        //是否获取锁
//        if (lock.tryLock()){

//            //从redis查询对象
//            RBucket<Object> bucket = redisson.getBucket("orderId:" + orderId);
//            //转换为order
//            FreOrder redisOrder = (FreOrder) bucket;

            String str = new String();
            str = "支付宝支付成功";

//            if (!bucket.isExists()){
//                //redis取出的order对象为空时就去查数据库
//
//                //存redis
//                bucket.set(orderDB,2, TimeUnit.HOURS);
//
//                //执行数据库操作
//                return Result.newInstance().setData(str);
//            }
            FreOrder orderDB = fos.getById(orderId);
            if (orderDB == null){
                throw new OrderException("订单不存在",3004);
            }
            if (orderDB.getOrderStatus() == 1){
                throw new OrderException("订单已支付过，请勿重复支付",3009);
            }
            //把从数据库查的order对象存放redis
            orderDB.setOrderPayway("支付宝");
            //将状态设为已支付
            orderDB.setOrderStatus(1);
//            if (redisOrder.getOrderStatus() == 1){
//                throw new OrderException("订单已支付过，请勿重复支付",3009);
//            }
//            redisOrder.setOrderPayway("支付宝");
//            //将状态设为已支付
//            redisOrder.setOrderStatus(1);
//            //修改数据库订单状态，返回支付成功
//            fos.saveOrUpdate(redisOrder);
            fos.saveOrUpdate(orderDB);

            //操作完数据库后解锁
//            lock.unlock();
            return Result.newInstance().setData(str);
//        }else {
//            throw new FreshException("服务器繁忙，请稍后再试",5005);
//        }

    }

    /**
     * 模拟微信支付
     * @return
     */
    @Override
    @GlobalTransactional
    public Result<String> payForWX(Integer orderId) throws JsonProcessingException {

        //获取锁对象
        RLock lock = redisson.getLock("payForWX");

        //是否获取锁
        if (lock.tryLock()){
            //从redis查询对象
            RBucket<Object> bucket = redisson.getBucket("orderId:" + orderId);
            //转换为order
            FreOrder redisOrder = (FreOrder) bucket;

            String str = new String();
            str = "微信支付成功";

            if (redisOrder == null){
                //redis取出的order对象为空时就去查数据库
                FreOrder orderDB = fos.getById(orderId);
                if (orderDB == null){
                    throw new OrderException("订单不存在",3004);
                }
                if (orderDB.getOrderStatus() == 1){
                    throw new OrderException("订单已支付过，请勿重复支付",3009);
                }
                //把从数据库查的order对象存放redis
                orderDB.setOrderPayway("微信");
                //将状态设为已支付
                orderDB.setOrderStatus(1);
                //存redis
                bucket.set(orderDB,2, TimeUnit.HOURS);

                //执行数据库操作
                fos.saveOrUpdate(orderDB);
                return Result.newInstance().setData(str);
            }
            if (redisOrder.getOrderStatus() == 1){
                throw new OrderException("订单已支付过，请勿重复支付",3009);
            }
            redisOrder.setOrderPayway("微信");
            //将状态设为已支付
            redisOrder.setOrderStatus(1);
            //修改数据库订单状态，返回支付成功
            fos.saveOrUpdate(redisOrder);
            //操作完数据库后解锁
            lock.unlock();
            return Result.newInstance().setData(str);
        }else {
            throw new FreshException("服务器繁忙，请稍后再试",5005);
        }


    }

    /**
     * 判断所有order是否存在所有id列表
     * @param judgeOrderIdsParam
     * @return
     */
    @Override
    public Result<Boolean> judgeOrderIds(JudgeOrderIdsParam judgeOrderIdsParam) {
        if (fos.judgeOrderIds(judgeOrderIdsParam)) {
            return Result.newInstance().setMessage("所有订单列表存在").setData(true);
        }
        return Result.newInstance().setCode(500).setMessage("有订单不存在").setData(false);
    }

    /**
     * 修改多个订单的状态
     * @param updateOrderListStatusParam
     * @return
     */
    @Override
    @GlobalTransactional
    public Result<Integer> updateOrderListStatus(UpdateOrderListStatusParam updateOrderListStatusParam) {
        return Result.newInstance().setMessage("修改成功，修改后的状态为").setData(fos.updateOrderListStatus(updateOrderListStatusParam));
    }

    /**
     * 取消订单
     * @param cancelOrderByOrderIdParam
     * @return
     */
    @Override
    public Result<String> cancelOrderByOrderId(CancelOrderByOrderIdParam cancelOrderByOrderIdParam) {
        return Result.newInstance().setMessage("取消订单成功").setData(fos.cancelOrderByOrderId(cancelOrderByOrderIdParam));
    }

}

